package it.intecs.pisa.smarcos.receivers;

import it.intecs.pisa.smarcos.R;
import it.intecs.pisa.smarcos.base.SpeechManager;
import it.intecs.pisa.smarcos.base.XMLParser;
import it.intecs.pisa.smarcos.services.WirelessDiscoveryService;
import it.intecs.pisa.smarcos.util.MathUtils;

import java.util.Date;
import java.text.DateFormat;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.wifi.SupplicantState;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.util.Log;


/** WIFI_STATE_CHANGED_ACTION 
 ** SUPPLICANT_STATE_CHANGED_ACTION
 ** SUPPLICANT_CONNECTION_CHANGE_ACTION
 ** SCAN_RESULTS_AVAILABLE_ACTION
 ** NETWORK_STATE_CHANGED_ACTION
 **/


public class WifiScanResultsBroadcastReceiver extends BroadcastReceiver {
	private static final String TAG = WifiScanResultsBroadcastReceiver.class.getSimpleName();
	
	protected static boolean connected = false;
	private SpeechManager speechManager;
	XMLParser menuMan;
	
	public void setConnected(){
		connected = false;
	}
	
	@Override
	public void onReceive(Context context, Intent intent) {

		speechManager = SpeechManager.getInstance(context);
		menuMan = XMLParser.getInstance(null,null);
		
		WifiManager mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
		WifiInfo conInfo = mWifiManager.getConnectionInfo();
		Log.d(TAG, "" + conInfo);
		
		String action = intent.getAction();
		Log.d(TAG, "action : " + action);

		// Broadcast intent action indicating that Wi-Fi has been enabled, disabled, enabling, disabling, or unknown
		if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)){
			/**
			 *  WIFI_STATE_DISABLED   1
			 *  WIFI_STATE_DISABLING  0 
			 *  WIFI_STATE_ENABLED    3
			 *  WIFI_STATE_ENABLING   2
			 *  WIFI_STATE_UNKNOWN    4
			 */
			
			Log.d(TAG, "--------------------------------------------------------------------");		
			Log.d(TAG, "1)  WIFI_STATE_CHANGED_ACTION");
			Log.d(TAG, "1)  EXTRA_WIFI_STATE: " + intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, 0));
			Log.d(TAG, "1)  EXTRA_PREVIOUS_WIFI_STATE: " + intent.getIntExtra(WifiManager.EXTRA_PREVIOUS_WIFI_STATE, 0));
			Log.d(TAG, "--------------------------------------------------------------------");
		}
		
		// Broadcast intent action indicating that the state of establishing a connection to an access point has 
		// changed.One extra provides the new SupplicantState.
		if (action.equals(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION)){
			Log.d(TAG, "--------------------------------------------------------------------");		
			Log.d(TAG, "2)  SUPPLICANT_STATE_CHANGED_ACTION");
			Log.d(TAG, "2)  EXTRA_NEW_STATE: " + intent.getIntExtra(WifiManager.EXTRA_NEW_STATE, 0));
			Log.d(TAG, "--------------------------------------------------------------------");
		}
		
		// Broadcast intent action indicating that a connection to the supplicant has been established 
		// (and it is now possible to perform Wi-Fi operations) or the connection to the supplicant has been lost.
		if (action.equals(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION)){
						
			/*Log.d(TAG, "--------------------------------------------------------------------");		
			Log.d(TAG, "3)  SUPPLICANT_CONNECTION_CHANGE_ACTION " + intent.getBooleanExtra(WifiManager.EXTRA_SUPPLICANT_CONNECTED, false));
			Log.d(TAG, "--------------------------------------------------------------------");
			//if (intent.getBooleanExtra(WifiManager.EXTRA_SUPPLICANT_CONNECTED, false) == false)*/
				//speechManager.say("Connection lost", true, true);
		}
		
		if (action.equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)){
			/*Log.d(TAG, "--------------------------------------------------------------------");		
			Log.d(TAG, "4)  SCAN_RESULTS_AVAILABLE_ACTION");
			Log.d(TAG, "--------------------------------------------------------------------");*/
		}
		
		// Broadcast intent action indicating that the state of Wi-Fi connectivity has changed.
		if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)){
			/*Log.d(TAG, "--------------------------------------------------------------------");		
			Log.d(TAG, "5)  NETWORK_STATE_CHANGED_ACTION");
			Log.d(TAG, "--------------------------------------------------------------------");*/
		}
	
		if (action.equals(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION)){

			if ((conInfo.getSupplicantState() == SupplicantState.COMPLETED ) && (conInfo.getSSID() != null)){
				if(checkIfSmarcosNetwork(conInfo) == false){
					Log.i(TAG,"Disconnecting from extraneous network. joining SMARCOS one");
					mWifiManager.disconnect();
				}
				else 
				{
					if (connected == false){
						connected = true;	

						Log.d(TAG,"SMARCOS network joined: stop scanning");

						speechManager.say("SMARCOS network joined", true, true);

						menuMan.addNotification(context.getString(R.string.MV_Notification_Wifi_Joined), 
								context.getString(R.string.MV_Notification_Wifi_Joined) +  "\n" + conInfo.getSSID() + 
								"\n at \n" + DateFormat.getDateTimeInstance().format(new Date()));
						
						SendConnectionStatus("CONNECTED", context);
					}
					return;
				}
			}
			
			if ((conInfo.getSupplicantState() == SupplicantState.DISCONNECTED))
			{
				if (connected == true){
					connected = false;

					Log.d(TAG,"SMARCOS network disconnected");

					speechManager.say("SMARCOS network lost", true, true);

					// Non e' necessario rieseguire lo startScan perche' non ha mai smesso.
					menuMan.addNotification(context.getString(R.string.MV_Notification_Wifi_Lost), 
								context.getString(R.string.MV_Notification_Wifi_Lost) + "\n" + conInfo.getSSID() +
								"\n at \n" + DateFormat.getDateTimeInstance().format(new Date()));
					
					SendConnectionStatus("DISCONNECTED", context);
				}	
				return;
			}
		}
	}


	void SendConnectionStatus(String status, Context context){

		Log.d(TAG,"SendConnectionStatus");
		
		Intent connectionIntent=new Intent("it.intecs.pisa.smarcos.services.ConnectionStatusReceiver.SHOW");

		connectionIntent.putExtra("ConnectionStatus", status); 
		connectionIntent.addCategory(Intent.CATEGORY_DEFAULT);					
		context.sendBroadcast(connectionIntent);
	}

	private boolean checkIfSmarcosNetwork(WifiInfo conInfo) {
		return conInfo.getSSID().equals(WirelessDiscoveryService.WIFI_SSID);
	}

}
